package cn.tedu._05weibo.exception;

import cn.tedu._05weibo.commen.response.JsonResult;
import cn.tedu._05weibo.commen.response.StatusCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;

/**
 * SpringMVC全局异常处理器
 * ControllerAdvice注解: 标识指定类为全局异常处理器
 * RestControllerAdvice注解: ControllerAdvice和ResponseBody的组合注解
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 异常处理方法-非法参数异常
     */
    @ExceptionHandler
    public JsonResult handleIllegalArgumentException(IllegalArgumentException iae) {
        //打桩
        log.error(iae.toString());
        //返回数据
        return new JsonResult(StatusCode.OPERATION_FAILED, iae.getMessage());
    }

    /**
     * 异常处理方法-方法参数无效异常
     */
    @ExceptionHandler
    public JsonResult handleMethodArgumentNotValidException(MethodArgumentNotValidException manve) {
        //打桩
        log.error(manve.toString());
        //返回数据
        //exception.getFieldError().getDefaultMessage()
        return new JsonResult(StatusCode.VALIDATED_ERROR, manve.getFieldError().getDefaultMessage());
    }

    /**
     * 异常处理方法-违反约束异常
     */
    @ExceptionHandler
    public JsonResult handleConstraintViolationException(ConstraintViolationException cve){
        //打桩
        log.error(cve.toString());
        //返回数据
        return new JsonResult(StatusCode.VALIDATED_ERROR,cve.getMessage().split(": ")[1]);
    }

    /**
     * 异常处理方法-空指针异常
     */
    @ExceptionHandler
    public JsonResult handleNullPointerException(NullPointerException npe){
        //打桩
        log.error(npe.toString());
        //返回数据
        return new JsonResult(StatusCode.NOT_LOGIN, npe.getMessage());
    }

    /**
     * 父类异常处理方法-运行异常(兜底)
     */
    @ExceptionHandler
    public JsonResult handleRuntimeException(RuntimeException re) {
        //打桩
        log.error(re.toString());
        //返回数据
        return new JsonResult(StatusCode.OPERATION_FAILED, re.getMessage());
    }

    /**
     * 超类异常处理方法(终极兜底, 最后定义)
     */
    @ExceptionHandler
    public JsonResult handleThrowable(Throwable throwable){
        //打桩
        log.error(throwable.toString());
        //返回数据
        return new JsonResult(StatusCode.THROWABLE_ERROR,throwable.getMessage());
    }
}
